this.emit('window-drag-end');
},
- // Returns the scale the Overview has when we just start zooming out
- // to overview mode. That is, when just the active workspace is showing.
- getZoomedInScale : function() {
- return 1 / this.workspaces.getScale();
- },
-
- // Returns the position the Overview has when we just start zooming out
- // to overview mode. That is, when just the active workspace is showing.
- getZoomedInPosition : function() {
- let [posX, posY] = this.workspaces.getActiveWorkspacePosition();
- let scale = this.getZoomedInScale();
-
- return [- posX * scale, - posY * scale];
- },
-
- // Returns the current scale of the Overview.
- getScale : function() {
- return this.workspaces.actor.scaleX;
- },
-
- // Returns the current position of the Overview.
- getPosition : function() {
- return [this.workspaces.actor.x, this.workspaces.actor.y];
- },
-
// show:
//
// Animates the overview visible and grabs mouse and keyboard input
});
}
- // Create a zoom out effect. First scale the workspaces view up and
- // position it so that the active workspace fills up the whole screen,
- // then transform it to its normal dimensions and position.
- // The opposite transition is used in hide().
- this.workspaces.actor.scaleX = this.workspaces.actor.scaleY = this.getZoomedInScale();
- [this.workspaces.actor.x, this.workspaces.actor.y] = this.getZoomedInPosition();
- let primary = global.get_primary_monitor();
- Tweener.addTween(this.workspaces.actor,
- { x: primary.x - this._group.x,
- y: primary.y - this._group.y,
- scaleX: 1,
- scaleY: 1,
- transition: 'easeOutQuad',
- time: ANIMATION_TIME,
- onComplete: this._showDone,
- onCompleteScope: this
- });
-
- // Make the other elements fade in.
this._group.opacity = 0;
Tweener.addTween(this._group,
{ opacity: 255,
transition: 'easeOutQuad',
- time: ANIMATION_TIME
+ time: ANIMATION_TIME,
+ onComplete: this._showDone,
+ onCompleteScope: this
});
this._coverPane.raise_top();
this.workspaces.hide();
- // Create a zoom in effect by transforming the workspaces view so that
- // the active workspace fills up the whole screen. The opposite
- // transition is used in show().
- let scale = this.getZoomedInScale();
- let [posX, posY] = this.getZoomedInPosition();
- Tweener.addTween(this.workspaces.actor,
- { x: posX,
- y: posY,
- scaleX: scale,
- scaleY: scale,
- transition: 'easeOutQuad',
- time: ANIMATION_TIME,
- onComplete: this._hideDone,
- onCompleteScope: this
- });
-
// Make other elements fade out.
Tweener.addTween(this._group,
{ opacity: 0,
transition: 'easeOutQuad',
- time: ANIMATION_TIME
+ time: ANIMATION_TIME,
+ onComplete: this._hideDone,
+ onCompleteScope: this
});
this._coverPane.raise_top();
this._windowClone = windowClone;
this._parentActor = parentActor;
+ this._hidden = false;
let title = new St.Label({ style_class: 'window-caption',
text: metaWindow.title });
},
hide: function() {
+ this._hidden = true;
this.closeButton.hide();
this.title.hide();
},
show: function() {
+ this._hidden = false;
let [x, y, mask] = global.get_pointer();
let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE,
x, y);
},
fadeIn: function() {
+ this.show();
this.title.opacity = 0;
- this.title.show();
this._parentActor.raise_top();
Tweener.addTween(this.title,
{ opacity: 255,
},
_onEnter: function() {
+ // We might get enter events on the clone while the overlay is
+ // hidden, e.g. during animations, we ignore these events,
+ // as the close button will be shown as needed when the overlays
+ // are shown again
+ if (this._hidden)
+ return;
this._parentActor.raise_top();
this.closeButton.show();
this.emit('show-close-button');
Signals.addSignalMethods(WindowOverlay.prototype);
const WindowPositionFlags = {
- ZOOM: 1 << 0,
+ INITIAL: 1 << 0,
ANIMATE: 1 << 1
};
// When dragging a window, we use this slot for reserve space.
this._reservedSlot = null;
this.metaWorkspace = metaWorkspace;
+ this._x = 0;
+ this._y = 0;
+ this._width = 0;
+ this._height = 0;
+
this._windowOverlaysGroup = new Clutter.Group();
// Without this the drop area will be overlapped.
this._windowOverlaysGroup.set_size(0, 0);
this.actor = new Clutter.Group();
- this.actor._delegate = this;
+ this.actor.set_size(0, 0);
- this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
+ this._dropRect = new Clutter.Rectangle({ opacity: 0 });
+ this._dropRect._delegate = this;
- // Items in _windowOverlaysGroup should not be scaled, so we don't
- // add them to this.actor, but to its parent whenever it changes
- this.actor.connect('parent-set', Lang.bind(this, this._onParentSet));
+ this.actor.add_actor(this._dropRect);
+ this.actor.add_actor(this._windowOverlaysGroup);
- // Auto-sizing is unreliable in the presence of ClutterClone, so rather than
- // implicitly counting on the workspace actor to be sized to the size of the
- // included desktop actor clone, set the size explicitly to the screen size.
- // See http://bugzilla.openedhand.com/show_bug.cgi?id=1755
- this.actor.width = global.screen_width;
- this.actor.height = global.screen_height;
- this.scale = 1.0;
+ this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
let windows = Main.getWindowActorsForWorkspace(this.metaWorkspace.index());
this.leavingOverview = false;
},
+ setGeometry: function(x, y, width, height) {
+ this._x = x;
+ this._y = y;
+ this._width = width;
+ this._height = height;
+
+ // This is sometimes called during allocation, so we do this later
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
+ function () {
+ this._dropRect.set_position(x, y);
+ this._dropRect.set_size(width, height);
+ return false;
+ }));
+
+ },
+
_lookupIndex: function (metaWindow) {
for (let i = 0; i < this._windows.length; i++) {
if (this._windows[i].metaWindow == metaWindow) {
return -1;
},
- _onParentSet: function(actor, old_parent) {
- let new_parent = this.actor.get_parent();
- if (new_parent == null)
- return;
-
- if (old_parent)
- this._windowOverlaysGroup.reparent(new_parent);
- else
- new_parent.add_actor(this._windowOverlaysGroup);
- },
-
containsMetaWindow: function (metaWindow) {
return this._lookupIndex(metaWindow) >= 0;
},
actorWidth = actor.width * actor.scale_x;
actorHeight = actor.height * actor.scale_y;
- xDelta = actor.x + actorWidth / 2.0 - xCenter * global.screen_width;
- yDelta = actor.y + actorHeight / 2.0 - yCenter * global.screen_height;
+ xDelta = actor.x + actorWidth / 2.0 - xCenter * this._width - this._x;
+ yDelta = actor.y + actorHeight / 2.0 - yCenter * this._height - this._y;
distanceSquared = xDelta * xDelta + yDelta * yDelta;
return distanceSquared;
},
/**
- * _getSlotRelativeGeometry:
+ * _getSlotGeometry:
* @slot: A layout slot
*
- * Returns: the workspace-relative [x, y, width, height]
+ * Returns: the screen-relative [x, y, width, height]
* of a given window layout slot.
*/
- _getSlotRelativeGeometry: function(slot) {
+ _getSlotGeometry: function(slot) {
let [xCenter, yCenter, fraction] = slot;
- let width = global.screen_width * fraction;
- let height = global.screen_height * fraction;
+ let width = this._width * fraction;
+ let height = this._height * fraction;
- let x = xCenter * global.screen_width - width / 2;
- let y = yCenter * global.screen_height - height / 2;
+ let x = this._x + xCenter * this._width - width / 2 ;
+ let y = this._y + yCenter * this._height - height / 2;
return [x, y, width, height];
},
/**
- * _computeWindowRelativeLayout:
+ * _computeWindowLayout:
* @metaWindow: A #MetaWindow
* @slot: A layout slot
*
* Given a window and slot to fit it in, compute its
- * workspace-relative [x, y, scale] where scale applies
+ * screen-relative [x, y, scale] where scale applies
* to both X and Y directions.
*/
- _computeWindowRelativeLayout: function(metaWindow, slot) {
- let [xCenter, yCenter, fraction] = slot;
- let [x, y, width, height] = this._getSlotRelativeGeometry(slot);
-
- xCenter = xCenter * global.screen_width;
+ _computeWindowLayout: function(metaWindow, slot) {
+ let [x, y, width, height] = this._getSlotGeometry(slot);
let rect = metaWindow.get_outer_rect();
let buttonOuterHeight, captionHeight;
if (this._windowOverlays[0]) {
[buttonOuterHeight, captionHeight] = this._windowOverlays[0].chromeHeights();
- buttonOuterWidth = this._windowOverlays[0].chromeWidth() / this.scale;
+ buttonOuterWidth = this._windowOverlays[0].chromeWidth();
} else
[buttonOuterHeight, captionHeight] = [0, 0];
- buttonOuterHeight /= this.scale;
- captionHeight /= this.scale;
- let desiredWidth = global.screen_width * fraction;
- let desiredHeight = global.screen_height * fraction;
- let scale = Math.min((desiredWidth - buttonOuterWidth) / rect.width,
- (desiredHeight - buttonOuterHeight - captionHeight) / rect.height,
- 1.0 / this.scale);
+ let scale = Math.min((width - buttonOuterWidth) / rect.width,
+ (height - buttonOuterHeight - captionHeight) / rect.height,
+ 1.0);
- x = Math.floor(xCenter - 0.5 * scale * rect.width);
+ x = Math.floor(x + (width - scale * rect.width) / 2);
// We want to center the window in case we have just one
if (metaWindow.get_workspace().n_windows == 1)
- y = Math.floor(yCenter * global.screen_height - 0.5 * scale * rect.height);
+ y = Math.floor(y + (height - scale * rect.height) / 2);
else
y = Math.floor(y + height - rect.height * scale - captionHeight);
/**
* positionWindows:
* @flags:
- * ZOOM - workspace is moving at the same time and we need to take that into account.
+ * INITIAL - this is the initial positioning of the windows.
* ANIMATE - Indicates that we need animate changing position.
*/
positionWindows : function(flags) {
if (this._reservedSlot)
clones.push(this._reservedSlot);
- let workspaceZooming = flags & WindowPositionFlags.ZOOM;
+ let initialPositioning = flags & WindowPositionFlags.INITIAL;
let animate = flags & WindowPositionFlags.ANIMATE;
// Start the animations
if (clone.inDrag)
continue;
- let [x, y, scale] = this._computeWindowRelativeLayout(metaWindow, slot);
+ let [x, y, scale] = this._computeWindowLayout(metaWindow, slot);
if (overlay)
overlay.hide();
/* Hidden windows should fade in and grow
* therefore we need to resize them now so they
* can be scaled up later */
- if (workspaceZooming) {
+ if (initialPositioning) {
clone.actor.opacity = 0;
clone.actor.scale_x = 0;
clone.actor.scale_y = 0;
y: y,
scale_x: scale,
scale_y: scale,
- workspace_relative: workspaceZooming ? this : null,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
let clone = clones[i];
let metaWindow = clone.metaWindow;
if (i == 0) {
- clone.setStackAbove(null);
+ clone.setStackAbove(this._dropRect);
} else {
let previousClone = clones[i - 1];
clone.setStackAbove(previousClone.actor);
// be after the workspace animation finishes.
let [cloneX, cloneY] = clone.actor.get_position();
let [cloneWidth, cloneHeight] = clone.actor.get_size();
- cloneX = this.x + this.scale * cloneX;
- cloneY = this.y + this.scale * cloneY;
- cloneWidth = this.scale * clone.actor.scale_x * cloneWidth;
- cloneHeight = this.scale * clone.actor.scale_y * cloneHeight;
+ cloneWidth = clone.actor.scale_x * cloneWidth;
+ cloneHeight = clone.actor.scale_y * cloneHeight;
if (overlay) {
overlay.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight);
return true;
let [x, y, mask] = global.get_pointer();
- let wsWidth = this.actor.width * this.scale;
- let wsHeight = this.actor.height * this.scale;
let pointerHasMoved = (this._cursorX != x && this._cursorY != y);
- let inWorkspace = (this.x < x && x < this.x + wsWidth &&
- this.y < y && y < this.y + wsHeight);
+ let inWorkspace = (this._x < x && x < this._x + this._width &&
+ this._y < y && y < this._y + this._height);
if (pointerHasMoved && inWorkspace) {
// store current cursor position
let clone = this._addWindowClone(win);
if (win._overviewHint) {
- let x = (win._overviewHint.x - this.actor.x) / this.scale;
- let y = (win._overviewHint.y - this.actor.y) / this.scale;
- let scale = win._overviewHint.scale / this.scale;
+ let x = win._overviewHint.x - this.actor.x;
+ let y = win._overviewHint.y - this.actor.y;
+ let scale = win._overviewHint.scale;
delete win._overviewHint;
clone.actor.set_position (x, y);
clone.actor.set_scale (scale, scale);
+ } else {
+ // Position new windows at the top corner of the workspace rather
+ // than where they were placed for real to avoid the window
+ // being clipped to the workspaceView. Its not really more
+ // natural for the window to suddenly appear in the overview
+ // on some seemingly random location anyway.
+ clone.actor.set_position (this._x, this._y);
}
this.positionWindows(WindowPositionFlags.ANIMATE);
// Animate the full-screen to Overview transition.
zoomToOverview : function() {
- this.actor.set_position(this.x, this.y);
- this.actor.set_scale(this.scale, this.scale);
-
// Position and scale the windows.
if (Main.overview.animationInProgress)
- this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.ZOOM);
+ this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.INITIAL);
else
- this.positionWindows(WindowPositionFlags.ZOOM);
+ this.positionWindows(WindowPositionFlags.INITIAL);
},
// Animates the return from Overview mode
this._overviewHiddenId = Main.overview.connect('hidden', Lang.bind(this,
this._doneLeavingOverview));
- if (this._metaWorkspace == currentWorkspace)
+ if (this.metaWorkspace != currentWorkspace)
return;
// Position and scale the windows.
y: clone.origY,
scale_x: 1.0,
scale_y: 1.0,
- workspace_relative: this,
time: Overview.ANIMATION_TIME,
opacity: 255,
transition: 'easeOutQuad'
{ scale_x: 0,
scale_y: 0,
opacity: 0,
- workspace_relative: this,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad'
});
};
Signals.addSignalMethods(Workspace.prototype);
-
-// Create a SpecialPropertyModifier to let us move windows in a
-// straight line on the screen even though their containing workspace
-// is also moving.
-Tweener.registerSpecialPropertyModifier('workspace_relative', _workspaceRelativeModifier, _workspaceRelativeGet);
-
-function _workspaceRelativeModifier(workspace) {
- let [startX, startY] = Main.overview.getPosition();
- let overviewPosX, overviewPosY, overviewScale;
-
- if (!workspace)
- return [];
-
- if (workspace.leavingOverview) {
- let [zoomedInX, zoomedInY] = Main.overview.getZoomedInPosition();
- overviewPosX = { begin: startX, end: zoomedInX };
- overviewPosY = { begin: startY, end: zoomedInY };
- overviewScale = { begin: Main.overview.getScale(),
- end: Main.overview.getZoomedInScale() };
- } else {
- overviewPosX = { begin: startX, end: 0 };
- overviewPosY = { begin: startY, end: 0 };
- overviewScale = { begin: Main.overview.getScale(), end: 1 };
- }
-
- return [ { name: 'x',
- parameters: { workspacePos: workspace.x,
- overviewPos: overviewPosX,
- overviewScale: overviewScale } },
- { name: 'y',
- parameters: { workspacePos: workspace.y,
- overviewPos: overviewPosY,
- overviewScale: overviewScale } }
- ];
-}
-
-function _workspaceRelativeGet(begin, end, time, params) {
- let curOverviewPos = (1 - time) * params.overviewPos.begin +
- time * params.overviewPos.end;
- let curOverviewScale = (1 - time) * params.overviewScale.begin +
- time * params.overviewScale.end;
-
- // Calculate the screen position of the window.
- let screen = (1 - time) *
- ((begin + params.workspacePos) * params.overviewScale.begin +
- params.overviewPos.begin) +
- time *
- ((end + params.workspacePos) * params.overviewScale.end +
- params.overviewPos.end);
-
- // Return the workspace coordinates.
- return (screen - curOverviewPos) / curOverviewScale - params.workspacePos;
-}
const CONTROLS_POP_IN_TIME = 0.1;
-function WorkspacesView(width, height, x, y, workspaces) {
- this._init(width, height, x, y, workspaces);
+function WorkspacesView(workspaces) {
+ this._init(workspaces);
}
WorkspacesView.prototype = {
- _init: function(width, height, x, y, workspaces) {
+ _init: function(workspaces) {
this.actor = new St.Group({ style_class: 'workspaces-view' });
- this.actor.set_clip(x, y, width, height);
// The actor itself isn't a drop target, so we don't want to pick on its area
this.actor.set_size(0, 0);
function() {
let node = this.actor.get_theme_node();
this._spacing = node.get_length('spacing');
- this._computeWorkspacePositions();
+ this._updateWorkspaceActors(false);
}));
this.actor.connect('notify::mapped',
Lang.bind(this, this._onMappedChanged));
- this._width = width;
- this._height = height;
- this._x = x;
- this._y = y;
- this._zoomScale = 1.0;
+ this._width = 0;
+ this._height = 0;
+ this._x = 0;
+ this._y = 0;
this._spacing = 0;
- this._activeWorkspaceX = 0; // x offset of active ws while dragging
- this._activeWorkspaceY = 0; // y offset of active ws while dragging
this._lostWorkspaces = [];
this._animating = false; // tweening
this._scrolling = false; // swipe-scrolling
for (let w = 0; w < this._workspaces.length; w++)
this._workspaces[w].zoomToOverview();
}));
+ this._overviewShownId =
+ Main.overview.connect('shown',
+ Lang.bind(this, function() {
+ this.actor.set_clip(this._x, this._y, this._width, this._height);
+ }));
this._scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
lower: 0,
this._swipeScrollEndId = 0;
},
- setZoomScale: function(zoomScale) {
- if (zoomScale == this._zoomScale)
- return;
+ setGeometry: function(x, y, width, height) {
+ if (this._x == x && this._y == y &&
+ this._width == width && this._height == height)
+ return;
+ this._width = width;
+ this._height = height;
+ this._x = x;
+ this._y = y;
- this._zoomScale = zoomScale;
- if (this._zoomOut) {
- // If we are already zoomed out, then we have to reposition.
- // Note that when shown initially zoomOut is false, so we
- // won't trigger this.
-
- // setZoomScale can be invoked when the workspaces view is
- // reallocated. Since we just want to animate things to the
- // new position it seems OK to call updateWorkspaceActors
- // immediately - adding a tween doesn't immediately cause
- // a new allocation. But hide/show of the window overlays we
- // do around animation does, so we need to do it later.
- // This can be removed when we fix things to not hide/show
- // the window overlay.
- Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
- Lang.bind(this, function() {
- this._computeWorkspacePositions();
- this._updateWorkspaceActors(true);
- }));
- }
+ for (let i = 0; i < this._workspaces.length; i++)
+ this._workspaces[i].setGeometry(x, y, width, height);
},
_lookupWorkspaceForMetaWindow: function (metaWindow) {
activeWorkspace.actor.raise_top();
+ this.actor.remove_clip(this._x, this._y, this._width, this._height);
+
for (let w = 0; w < this._workspaces.length; w++)
this._workspaces[w].zoomFromOverview();
},
this.actor.destroy();
},
- getScale: function() {
- return this._workspaces[0].scale;
- },
-
syncStacking: function(stackIndices) {
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].syncStacking(stackIndices);
},
- // Get the grid position of the active workspace.
- getActiveWorkspacePosition: function() {
- let activeWorkspaceIndex = global.screen.get_active_workspace_index();
- let activeWorkspace = this._workspaces[activeWorkspaceIndex];
-
- return [activeWorkspace.x, activeWorkspace.y];
- },
-
- zoomOut: function() {
- if (this._zoomOut)
- return;
-
- this._zoomOut = true;
- this._computeWorkspacePositions();
- this._updateWorkspaceActors(true);
- },
-
- zoomIn: function() {
- if (!this._zoomOut)
- return;
-
- this._zoomOut = false;
- this._computeWorkspacePositions();
- this._updateWorkspaceActors(true);
- },
-
- // Compute the position, scale and opacity of the workspaces, but don't
- // actually change the actors to match
- _computeWorkspacePositions: function() {
- let active = global.screen.get_active_workspace_index();
- let zoomScale = this._zoomOut ? this._zoomScale : 1;
- let scale = zoomScale * this._width / global.screen_width;
-
- let _width = this._workspaces[0].actor.width * scale;
- let _height = this._workspaces[0].actor.height * scale;
-
- this._activeWorkspaceX = (this._width - _width) / 2;
- this._activeWorkspaceY = (this._height - _height) / 2;
-
- for (let w = 0; w < this._workspaces.length; w++) {
- let workspace = this._workspaces[w];
-
- workspace.opacity = (this._inDrag && w != active) ? 200 : 255;
-
- workspace.scale = scale;
- workspace.x = this._x + this._activeWorkspaceX;
-
- // We adjust the center because the zoomScale is to leave space for
- // the expanded workspace control so we want to zoom to either the
- // left part of the area or the right part of the area
- let offset = 0.5 * (1 - this._zoomScale) * this._width;
- let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
- if (this._zoomOut)
- workspace.x += rtl ? offset : - offset;
-
- // We divide by zoomScale so that adjacent workspaces are always offscreen
- // except when we are switching between workspaces
- workspace.y = this._y + this._activeWorkspaceY
- + (w - active) * (_height + this._spacing) / zoomScale;
- }
+ updateWindowPositions: function() {
+ for (let w = 0; w < this._workspaces.length; w++)
+ this._workspaces[w].positionWindows(Workspace.WindowPositionFlags.ANIMATE);
},
_scrollToActive: function(showAnimation) {
let active = global.screen.get_active_workspace_index();
- this._computeWorkspacePositions();
this._updateWorkspaceActors(showAnimation);
this._updateScrollAdjustment(active, showAnimation);
},
- // Update workspace actors parameters to the values calculated in
- // _computeWorkspacePositions()
+ // Update workspace actors parameters
// @showAnimation: iff %true, transition between states
_updateWorkspaceActors: function(showAnimation) {
let active = global.screen.get_active_workspace_index();
- let targetWorkspaceNewY = this._y + this._activeWorkspaceY;
- let targetWorkspaceCurrentY = this._workspaces[active].y;
- let dy = targetWorkspaceNewY - targetWorkspaceCurrentY;
this._animating = showAnimation;
Tweener.removeTweens(workspace.actor);
- workspace.y += dy;
+ let opacity = (this._inDrag && w != active) ? 200 : 255;
+ let y = (w - active) * (this._height + this._spacing);
if (showAnimation) {
- let params = { x: workspace.x,
- y: workspace.y,
- scale_x: workspace.scale,
- scale_y: workspace.scale,
- opacity: workspace.opacity,
+ let params = { y: y,
+ opacity: opacity,
time: WORKSPACE_SWITCH_TIME,
transition: 'easeOutQuad'
};
}
Tweener.addTween(workspace.actor, params);
} else {
- workspace.actor.set_scale(workspace.scale, workspace.scale);
- workspace.actor.set_position(workspace.x, workspace.y);
- workspace.actor.opacity = workspace.opacity;
+ workspace.actor.set_position(0, y);
+ workspace.actor.opacity = opacity;
if (w == 0)
this._updateVisibility();
}
Tweener.removeTweens(workspace.actor);
- workspace.y += dy;
workspace.actor.show();
workspace.hideWindowsOverlays();
this._lostWorkspaces[l].destroy();
this._lostWorkspaces = [];
- this._computeWorkspacePositions();
this._updateWorkspaceActors(false);
},
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++)
this.actor.add_actor(this._workspaces[w].actor);
- this._computeWorkspacePositions();
this._updateWorkspaceActors(false);
} else {
this._lostWorkspaces = lostWorkspaces;
_onDestroy: function() {
this._scrollAdjustment.run_dispose();
Main.overview.disconnect(this._overviewShowingId);
+ Main.overview.disconnect(this._overviewShownId);
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
if (this._timeoutId) {
Main.overview.hide();
}
- if (result == Overview.SwipeScrollResult.SWIPE)
- // The active workspace has changed; while swipe-scrolling
- // has already taken care of the positioning, the cached
- // positions need to be updated
- this._computeWorkspacePositions();
-
// Make sure title captions etc are shown as necessary
this._updateVisibility();
},
return;
let currentY = firstWorkspaceY;
- let newY = this._y - adj.value / (adj.upper - 1) * workspacesHeight;
+ let newY = - adj.value / (adj.upper - 1) * workspacesHeight;
let dy = newY - currentY;
this._workspaces[i] = new Workspace.Workspace(metaWorkspace);
}
- let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
-
- let totalAllocation = this.actor.allocation;
- let totalWidth = totalAllocation.x2 - totalAllocation.x1;
- let totalHeight = totalAllocation.y2 - totalAllocation.y1;
-
- let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
-
- totalWidth -= controlsVisible;
-
- // Workspaces expect to have the same ratio as the screen, so take
- // this into account when fitting the workspace into the available space
- let width, height;
- let totalRatio = totalWidth / totalHeight;
- let wsRatio = global.screen_width / global.screen_height;
- if (wsRatio > totalRatio) {
- width = totalWidth;
- height = Math.floor(totalWidth / wsRatio);
- } else {
- width = Math.floor(totalHeight * wsRatio);
- height = totalHeight;
- }
-
- // Position workspaces in the available space
- let [x, y] = this.actor.get_transformed_position();
- x = Math.floor(x + Math.abs(totalWidth - width) / 2);
- y = Math.floor(y + Math.abs(totalHeight - height) / 2);
-
- if (rtl)
- x += controlsVisible;
-
- let newView = new WorkspacesView(width, height, x, y, this._workspaces);
- this._updateZoomScale();
-
if (this.workspacesView)
this.workspacesView.destroy();
- this.workspacesView = newView;
+ this.workspacesView = new WorkspacesView(this._workspaces);
+ this._updateWorkspacesGeometry();
this._nWorkspacesNotifyId =
global.screen.connect('notify::n-workspaces',
childBox.y2 = box.y2- box.y1;
this._controls.allocate(childBox, flags);
- this._updateZoomScale();
+ this._updateWorkspacesGeometry();
},
- _updateZoomScale: function() {
+ _updateWorkspacesGeometry: function() {
if (!this.workspacesView)
return;
- let totalAllocation = this.actor.allocation;
- let totalWidth = totalAllocation.x2 - totalAllocation.x1;
- let totalHeight = totalAllocation.y2 - totalAllocation.y1;
+ let width = this.actor.allocation.x2 - this.actor.allocation.x1;
+ let height = this.actor.allocation.y2 - this.actor.allocation.y1;
- let [controlsMin, controlsNatural] = this._controls.get_preferred_width(totalHeight);
+ let [controlsMin, controlsNatural] = this._controls.get_preferred_width(height);
let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
- let zoomScale = (totalWidth - controlsNatural) / (totalWidth - controlsVisible);
- this.workspacesView.setZoomScale(zoomScale);
+ let [x, y] = this.actor.get_transformed_position();
+
+ let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
+
+ if (this._zoomOut) {
+ width -= controlsNatural;
+ if (rtl)
+ x += controlsNatural;
+ } else {
+ width -= controlsVisible;
+ if (rtl)
+ x += controlsVisible;
+ }
+
+ this.workspacesView.setGeometry(x, y, width, height);
},
_onRestacked: function() {
let shouldZoom = this._controls.hover || this._inDrag;
if (shouldZoom != this._zoomOut) {
this._zoomOut = shouldZoom;
+ this._updateWorkspacesGeometry();
if (!this.workspacesView)
return;
time: WORKSPACE_SWITCH_TIME,
transition: 'easeOutQuad' });
- if (shouldZoom)
- this.workspacesView.zoomOut();
- else
- this.workspacesView.zoomIn();
+ this.workspacesView.updateWindowPositions();
}
},